home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
101-125
/
scopedisk102
/
bmorph
/
biomorph.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-19
|
18KB
|
883 lines
/*
BioMorph
By: Chris MacDonald & Steve Martin
Version: 1.0
Last Revision: 28 July 89
*/
#ifdef LATTICE
#include <proto/all.h>
#include <stdlib.h>
/* Prototypes for functions defined in biomorph.c */
int main(int argc,
unsigned char **argv);
void mousezoom(unsigned short code);
void genmorph(void);
void analyze(unsigned short Menunumber);
void open_all(void);
void close_all(void);
#endif
#include <exec/types.h>
#include <intuition/intuition.h>
#include <stdio.h>
#include <graphics/gfxmacros.h>
#include <math.h>
/*
system functions
*/
extern struct Screen *OpenScreen ();
extern struct Window *OpenWindow();
extern struct Library *OpenLibrary();
extern struct ViewPort *ViewPortAddress();
/*
system variables
*/
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct MathBase *MathBase;
struct Screen *s;
struct Window *w;
struct IntuiMessage *msg;
struct RastPort *rp;
struct ViewPort *vp;
/*
menu stuff
*/
struct TextAttr Font =
{
(STRPTR)"topaz.font",
TOPAZ_SIXTY,
FS_NORMAL,
FPF_ROMFONT
};
struct IntuiText GenerateText = {4,1,JAM1,1,1,&Font,
(UBYTE *) " Generate",NULL};
struct IntuiText StopText ={4,1,JAM1,1,1,&Font,(UBYTE *)" Stop",NULL};
struct IntuiText QuitText ={4,1,JAM1,1,1,&Font,(UBYTE *)" Quit",NULL};
struct IntuiText GreyText = {4,1,JAM1,1,1,&Font,(UBYTE *) " Grey",NULL};
struct IntuiText RedText = {4,1,JAM1,1,1,&Font,(UBYTE *) " Red",NULL};
struct IntuiText GreenText = {4,1,JAM1,1,1,&Font,(UBYTE *)" Green",NULL};
struct IntuiText BlueText = {4,1,JAM1,1,1,&Font,(UBYTE *) " Blue",NULL};
struct IntuiText TwoText = {4,1,JAM1,1,1,&Font,(UBYTE *) " 2",NULL};
struct IntuiText FourText = {4,1,JAM1,1,1,&Font,(UBYTE *) " 4",NULL};
struct IntuiText EightText = {4,1,JAM1,1,1,&Font,(UBYTE *) " 8",NULL};
struct IntuiText SixteenText = {4,1,JAM1,1,1,&Font,(UBYTE *)" 16",NULL};
struct IntuiText TwentyText = {4,1,JAM1,1,1,&Font,(UBYTE *) " 20",NULL};
struct IntuiText SquareText ={4,1,JAM1,1,1,&Font,(UBYTE *)" z^2 + c",NULL};
struct IntuiText CubeText = {4,1,JAM1,1,1,&Font,(UBYTE *) " z^3 + c",NULL};
struct IntuiText FifthText = {4,1,JAM1,1,1,&Font,(UBYTE *)" z^5 + c",NULL};
struct MenuItem Quit =
{
NULL,1,26,140,10,ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ,
0,(APTR) &QuitText,NULL,0x51,NULL,0
};
struct MenuItem Stop =
{
&Quit,1,14,140,10,ITEMTEXT | ITEMENABLED | HIGHCOMP |
CHECKIT | COMMSEQ,0xfffffff9,(APTR) &StopText,NULL,0x53,NULL,0
};
struct MenuItem Generate =
{
&Stop,1,2,140,10,ITEMTEXT | ITEMENABLED | HIGHCOMP |
CHECKIT | CHECKED | COMMSEQ,0xfffffffa,(APTR) &GenerateText,
NULL,0x47,NULL,0
};
struct MenuItem Blue =
{
NULL,1,38,70,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
| CHECKIT,0xfffffff7,(APTR) &BlueText,NULL,0,NULL,0
};
struct MenuItem Green =
{
&Blue,1,26,70,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
| CHECKIT,0xfffffffb,(APTR) &GreenText,NULL,0,NULL,0
};
struct MenuItem Red =
{
&Green,1,14,70,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
| CHECKIT,0xfffffffd,(APTR) &RedText,NULL,0,NULL,0
};
struct MenuItem Grey =
{
&Red,1,2,70,10,ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKED
| CHECKIT,0xfffffffe,(APTR) &GreyText,NULL,0,NULL,0
};
struct MenuItem Twenty =
{
NULL,1,50,60,10,ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKED
| CHECKIT,0xffffffef,(APTR) &TwentyText,NULL,0,NULL,0
};
struct MenuItem Sixteen =
{
&Twenty,1,38,60,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
| CHECKIT,0xfffffff7,(APTR) &SixteenText,NULL,0,NULL,0
};
struct MenuItem Eight =
{
&Sixteen,1,26,60,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
| CHECKIT,0xfffffffb,(APTR) &EightText,NULL,0,NULL,0
};
struct MenuItem Four =
{
&Eight,1,14,60,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
| CHECKIT,0xfffffffd,(APTR) &FourText,NULL,0,NULL,0
};
struct MenuItem Two =
{
&Four,1,2,60,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
| CHECKIT,0xfffffffe,(APTR) &TwoText,NULL,0,NULL,0
};
struct MenuItem Fifth =
{
NULL,1,26,100,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
| CHECKIT,0xfffffffb,(APTR) &FifthText,NULL,0,NULL,0
};
struct MenuItem Cube =
{
&Fifth,1,14,100,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
| CHECKED | CHECKIT,0xfffffffd,(APTR) &CubeText,NULL,0,NULL,0
};
struct MenuItem Square =
{
&Cube,1,2,100,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
| CHECKIT,0xfffffffe,(APTR) &SquareText,NULL,0,NULL,0
};
struct Menu Zx = {NULL,165,0,80,0,NULL,(BYTE *) "Equation",&Square};
struct Menu Zoom = {&Zx,115,0,50,0,NULL,(BYTE *) "Zoom",&Two};
struct Menu Colors = {&Zoom,55,0,60,0,MENUENABLED,(BYTE *) "Colors",&Grey};
struct Menu File = {&Colors,10,0,45,10,MENUENABLED,
(BYTE *) "File",&Generate};
/*
voidoids
*/
void open_all(), close_all(), initmenu();
void addplex(),multplex(),sqrplex(),cubeplex(),analyze(),genmorph();
void mousezoom();
/*
window and screen (windscreen?)
*/
struct NewScreen myScreen =
{
0,0,
320,200,
4,
1,0,
0,
CUSTOMSCREEN,
NULL,
(UBYTE *)"BioMorph 1.0",
NULL,
NULL
};
struct NewWindow myWindow =
{
80,9,
165, 160,
0,
1,
MENUPICK | MOUSEBUTTONS,
SMART_REFRESH | ACTIVATE | WINDOWSIZING |
WINDOWDRAG | GIMMEZEROZERO,
NULL,
NULL,
(UBYTE *)"z^3 + c",
NULL,
NULL,
50, 40,
210, 200,
WBENCHSCREEN
};
/*
color maps
*/
UWORD greycolortable[] =
{
0x004,0xfff,0x990,0x059,
0x666,0x777,0x888,0x999,
0xaaa,0xbbb,0xccc,0xddd,
0xeee,0xfff,0x000
};
UWORD redcolortable[] =
{
0x004,0xfff,0x990,0x059,
0x600,0x700,0x800,0x900,
0xa00,0xb00,0xc00,0xd00,
0xe00,0xf00,0x000
};
UWORD greencolortable[] =
{
0x004,0xfff,0x990,0x059,
0x060,0x070,0x080,0x090,
0x0a0,0x0b0,0x0c0,0x0d0,
0x0e0,0x0f0,0x000
};
UWORD bluecolortable[] =
{
0x004,0xfff,0x990,0x059,
0x006,0x007,0x008,0x009,
0x00a,0x00b,0x00c,0x00d,
0x00e,0x00f,0x000
};
/*
IDCMP stuff
*/
struct IntuiMessage *message;
USHORT MessageClass, MessageCode, MousX, MousY;
/*
global variable descriptions
creal, = real & imaginary portion of
cimag constant
magfactor = magnification factor of graph
fnum = function power value (2 = square,
3 = cube, 4 = z ^ 5)
stopflag = flag which tells genmorph() to
quit when Stop is selected from
File menu
minwinx, = minimum window size values, set
minwiny to insure user can't size window
down while generating graph
winx, = size of window user selects for
winy next graph
mxstart, = upper left corner value for mouse
mystart zoom box. transferred to xstart, ystart
in genmorph()
xstart, = upper left corner value of last generated
ystart or currently generating graph
increment = distance between adjacent graph points
size = size in pixels of most recently computed
or currently computing graph
*/
float creal, cimag, magfactor, xstart, ystart, mxstart, mystart, increment;
short fnum,stopflag,minwinx,minwiny,winx,winy,size;
main(argc,argv)
int argc;
UBYTE *argv[];
{
/*
user can enter a '?' or a complex constant
when starting the program
*/
printf("\nBioMorph 1.0\n\nby Chris MacDonald & Steve Martin\n\n");
if (argc == 1) /* no arguments */
{
creal = 0.5;
cimag = 0.0;
printf("Using default constant: real = 0.5\n");
printf(" imaginary = 0.0\n\n");
printf("Next time, try your own constant!\n\n");
printf("Usage: Biomorph (real) (imaginary)\n");
printf("Where real and imaginary are a complex constant\n\n");
Delay(125);
}
else if (argc == 2 && (*argv[1] == '?')) /* user types '?' */
{
printf("\nUsage: Biomorph (real) (imaginary)\n");
printf("Where real and imaginary are a complex constant\n\n");
exit(TRUE);
}
else
{
creal = atof(argv[1]); /* user enters complex constant */
cimag = 0.0;
if(argc >= 3) cimag = atof(argv[2]);
printf("\nComplex constant:\n");
printf("real = %f\n",creal);
printf("imaginary = %f\n\n",cimag);
Delay(130);
}
open_all(); /* opens libraries, screen and window */
LoadRGB4(vp,&greycolortable[0],15); /* load color table */
SetRast(rp,3); /* clear window */
/* default graph drawn when program starts */
magfactor = 20;
/*where upper left corner of graph should be */
mxstart = -1.0 * magfactor / 2.0;
mystart = mxstart;
fnum = 3; /* function is cube (z^3 + c) */
genmorph(); /* generate graph */
/* loop which waits for user to access menu */
while (1)
{
if((message = (struct IntuiMessage *)
GetMsg(w->UserPort)) == NULL)
{
Wait(1L << w->UserPort->mp_SigBit);
continue;
}
stopflag = 0;
MessageClass = message->Class; /* get needed data */
MessageCode = message->Code;
MousX = w->GZZMouseX;
MousY = w->GZZMouseY;
ReplyMsg((void *)message); /* respond to message */
switch(MessageClass)
{
case MENUPICK : analyze(MessageCode);
break; /* accessed menu */
case MOUSEBUTTONS : mousezoom(MessageCode);
break; /* pressed mouse button */
}
}
}
/*
mousezoom()'s purpose is to generate a "zoom box" while mouse button is
pressed and held down. When the button is released, the starting
coordinates and magnification of the selected box are computed.
*/
/* mousezoom variable descriptions
loop = flag indicating end of zoom
box loop
setx, = the starting window coordinates
sety of the zoom box
mx = x distance mouse moves from setx
*/
void mousezoom(code)
USHORT code; /* message code */
{
short loop = 1;
USHORT mx,setx,sety;
switch(code)
{
case SELECTDOWN : /*left button down*/
setx = MousX; /*set starting point of*/
sety = MousY; /*zoom box */
if(setx >= 215) setx = 0; /*fixes problem when mouse*/
if(sety >= 215) sety = 0; /*points to left | up edge*/
mx = w->GZZMouseX; /*get current mouse x position*/
SetWindowTitles(w,"Zooming!",(void *)-1);
SetDrMd(rp,COMPLEMENT); /* "self erasing" mode*/
SetAPen(rp,1);
Move(rp,setx,sety); /* draw the zoom box */
Draw(rp,mx,sety);
Draw(rp,mx,sety + mx - setx);
Draw(rp,setx,sety + mx -setx);
Draw(rp,setx,sety);
while (loop) /*adjusts zoom box while button down*/
{
while((message = (struct IntuiMessage *)
GetMsg(w->UserPort)) == NULL)
{
Move(rp,setx,sety); /* erase old box */
Draw(rp,mx,sety);
Draw(rp,mx,sety + mx - setx);
Draw(rp,setx,sety + mx -setx);
Draw(rp,setx,sety);
mx = w->GZZMouseX; /* get new x value */
/*stops dragging box to the left*/
if((mx < setx) || (mx > 400)) mx = setx;
Move(rp,setx,sety); /* draw new box */
Draw(rp,mx,sety);
Draw(rp,mx,sety + mx - setx);
Draw(rp,setx,sety + mx -setx);
Draw(rp,setx,sety);
}
MessageClass = message->Class; /*drops out of loop*/
MessageCode = message->Code; /*when a message */
ReplyMsg((void *)message); /*occurs */
switch(MessageClass)
{
case MOUSEBUTTONS:
switch(MessageCode)
{
case SELECTUP: /* user releases button */
/* set new mag & position based on zoom box */
magfactor =(mx - setx) * increment;
mxstart = xstart +
((setx - 2) * increment);
mystart = ystart +
((sety - 1) * increment);
SetWindowTitles(w,"Got it.",(void *) -1);
Delay(20);
switch(fnum) /* put window title back */
{
case 2:
SetWindowTitles(w,"z^2 + c",(void *) -1);
break;
case 3:
SetWindowTitles(w,"z^3 + c",(void *) -1);
break;
case 4:
SetWindowTitles(w,"z^5 + c",(void *) -1);
break;
}
Move(rp,setx,sety); /* erase box */
Draw(rp,mx,sety);
Draw(rp,mx,sety + mx - setx);
Draw(rp,setx,sety + mx -setx);
Draw(rp,setx,sety);
loop = 0; /* set flag to end loop */
break;
}
break;
}
}
}
}
void genmorph()
{
/*
x, = graph loop vars. derived from
y current window size
n = iteration loop variable
value = contains result of window sizing
call
zreal, = current equation coordinates
zimag
a, b = temporary storage for math routines
*/
short x,y,n,value;
float zreal,zimag,a,b;
SetDrMd(rp,JAM1);
stopflag = 0; /* flag to stop generating */
/* setting limits of window size */
winx = w->Width;
winy = w->Height;
value = WindowLimits(w,winx,winy,210,200);
/* how large the graph should be, based on window size */
if(winx < winy)
{
size = winx - 8;
}
else
{
size = winy - 8;
}
/* how much zreal&imag should be incremented each
time through loop */
increment = magfactor / size;
xstart = mxstart; /* assign mousezoom() values */
ystart = mystart;
for(y = 0; y <= size - 6; ++y) /* y graph loop */
{
for(x = 0; x <= size; ++x) /* x graph loop */
{
/* setting z value for current coordinates */
zreal = ((float) xstart + (increment * x));
zimag = ((float) ystart + (increment * y));
/* iteration loop */
for(n = 1; n <= 10; ++n)
{
a = zreal;
b = zimag;
if (fnum == 2) /* square */
{
zreal = a*a - b*b + creal;
zimag = 2*a*b + cimag;
}
else if (fnum == 3) /* cube */
{
zreal = a*(a*a - 3*b*b) + creal;
zimag = b*(3*a*a - b*b) + cimag;
}
else if (fnum == 4) /* fifth */
{
a = zreal;
b = zimag;
zreal = a * (a*a*a*a - 10*a*a*b*b + 5*b*b*b*b) + creal;
zimag = b * (5*a*a*a*a - 10*a*a*b*b + b*b*b*b) + cimag;
}
/* break out of loop if result is ever greater than ten */
if(fabs(zreal) > 10 || fabs(zimag) > 10 ||
(zreal*zreal + zimag*zimag) > 100)
break;
}
/* setting color of pixel based on value of z after iteration */
if(!(fabs(zreal) < 10 || fabs(zimag) < 10))
{
SetAPen(rp,14);
}
else if(fabs(zreal) < fabs(zimag))
{
SetAPen(rp,((short) fabs(zreal)) + 4);
}
else
{
SetAPen(rp,((short) fabs(zimag)) + 4);
}
WritePixel(rp,x,y);
}
/* test for menu access at end of each x loop */
/* clears all messages except newest */
MessageClass = NULL;
while(message = (struct IntuiMessage *)GetMsg(w->UserPort))
{
MessageClass = message->Class;
MessageCode = message->Code;
ReplyMsg((void *)message);
}
if(MessageClass)
{
switch(MessageClass)
{
case MENUPICK : analyze(MessageCode);
break;
}
}
/* quit generating if user picks Stop from File menu */
if(stopflag)
{
stopflag = 0;
x = size;
y = size - 6;
}
}
/* set window size limits back to normal */
value = WindowLimits(w,50,40,210,200);
/* enable zoom and power menus */
ClearMenuStrip(w);
Zx.Flags = MENUENABLED;
Zoom.Flags = MENUENABLED;
Stop.Flags |= CHECKED; /* set Stop checkmark */
Generate.Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP
| COMMSEQ | CHECKIT; /* unset Generate checkmark */
SetMenuStrip(w,&File);
DisplayBeep(NULL); /* flash screen when done */
}
/*
analyze(): responds to user menu access
*/
void analyze(Menunumber)
USHORT Menunumber;
{
USHORT Menu, MenuItem;
Menu = MENUNUM(Menunumber);
MenuItem = ITEMNUM(Menunumber);
switch(Menu)
{
case 0 : /* File Menu */
switch(MenuItem)
{
case 0 : /* Generate */
if (!(stopflag))
{
SetRast(rp,0);
ClearMenuStrip(w);
Zoom.Flags = NULL;
Zx.Flags = NULL;
SetMenuStrip(w,&File);
genmorph();
}
break;
case 1 : /* Stop */
stopflag = 1;
ClearMenuStrip(w);
Zoom.Flags = MENUENABLED;
Zx.Flags = MENUENABLED;
SetMenuStrip(w,&File);
break;
case 2 : /* Quit */
close_all();
exit(TRUE);
break;
}
break;
case 1 : /* Colors */
switch(MenuItem)
{
case 0 : /* Grey */
LoadRGB4(vp,&greycolortable[0],15);
break;
case 1 : /* Red */
LoadRGB4(vp,&redcolortable[0],15);
break;
case 2 : /* Green */
LoadRGB4(vp,&greencolortable[0],15);
break;
case 3 : /* Blue */
LoadRGB4(vp,&bluecolortable[0],15);
break;
}
break;
case 2 : /* Zoom */
switch(MenuItem)
{
case 0 :
magfactor = 2;
mxstart = -1.0 * magfactor / 2.0;
mystart = mxstart;
break;
case 1 :
magfactor = 4;
mxstart = -1.0 * magfactor / 2.0;
mystart = mxstart;
break;
case 2 :
magfactor = 8;
mxstart = -1.0 * magfactor / 2.0;
mystart = mxstart;
break;
case 3 :
magfactor = 16;
mxstart = -1.0 * magfactor / 2.0;
mystart = mxstart;
break;
case 4 :
magfactor = 20;
mxstart = -1.0 * magfactor / 2.0;
mystart = mxstart;
break;
}
break;
case 3 : /* Power */
switch(MenuItem)
{
case 0 :
fnum = 2;
SetWindowTitles(w,"z^2 + c",(void *) -1);
break;
case 1 :
fnum = 3;
SetWindowTitles(w,"z^3 + c",(void *) -1);
break;
case 2 :
fnum = 4;
SetWindowTitles(w,"z^5 + c",(void *) -1);
break;
}
break;
}
}
void open_all()
{
if((IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", 0L)) == NULL)
exit(1);
if((MathBase = (struct MathBase *)
OpenLibrary("mathffp.library", 0L)) == NULL)
exit(1);
if ((GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library", 0L)) == NULL)
exit(1);
if ((s = OpenScreen(&myScreen)) == NULL)
exit(1);
vp = &(s -> ViewPort);
myWindow.Screen = s;
myWindow.Type = CUSTOMSCREEN;
if ((w = OpenWindow(&myWindow)) == NULL)
exit(1);
rp = w->RPort;
SetMenuStrip(w,&File);
}
void close_all()
{
while(message = (struct IntuiMessage *)GetMsg(w->UserPort))
{
ReplyMsg((void *)message);
}
if (w) ClearMenuStrip(w);
if (w) CloseWindow(w);
if (s) CloseScreen(s);
if (GfxBase) CloseLibrary(GfxBase);
if (IntuitionBase) CloseLibrary(IntuitionBase);
}